<?php
$loader->requireOnce('includes/LabAssignment/LabAssignmentModel.class.php');
$loader->requireOnce('includes/LabQueue/LabQueueProcessor.class.php');
$loader->requireOnce('includes/LabException.class.php');
$loader->requireOnce('includes/EnumerationConstant.class.php');
$loader->requireOnce('includes/LabResult/LabResultEngine.class.php');
/**
 * Processor for lab assignment
 * @package modules.dept_laboratory.includes
 * @author viethd
 * @version $Id$
 * @copyright 2009 LHV Company
 */
class LabAssignmentProcessor {
	private $controller;
	private $logger ;
	function __construct($controller) {
		$this->controller = $controller;
		$this->logger = LoggerManager::getLogger('modules.dept_laboratory.includes.LabAssignment.LabAssignmentProcessor');
	}
	/**
	 * Render assignment page.
	 * @return html
	 */
	public function renderAssignmentPage($ticketId) {
		$employeeObj = Celini::newORDO("Employee");
		$doctorList = $employeeObj->getEmployeeOfDepartment($this->controller->_me->get_department_id(),EmployeeType::DOCTOR_ID, true);
		$labAssignmentModel = new LabAssignmentModel();
		$this->controller->assign('doctorList', $doctorList);
		$this->controller->assign('ticketId', $ticketId);
		$this->controller->assign('labAssignmentModel', $labAssignmentModel->labGroupModelToArray());
		$orders =   L10nHelper::getYMDorder();
		$this->controller->assign('datePart_0', $orders[0]);
		$this->controller->assign('datePart_1', $orders[1]);
		$this->controller->assign('datePart_2', $orders[2]);
		return $this->controller->view->render('laboratory_assignment.html');

	}
	/**
	 * Render assignment page.
	 * @return html
	 */
	public function renderAssignmentPage4VEdit($ticketId, $labAssignmentTicketId) {
		$result = array('');
		$employeeObj = Celini::newORDO("Employee");
		$doctorList = $employeeObj->getEmployeeOfDepartment($this->controller->_me->get_department_id(),EmployeeType::DOCTOR_ID, true);
		$labAssignmentModel = new LabAssignmentModel();
		$this->controller->assign('doctorList', $doctorList);
		$this->controller->assign('ticketId', $ticketId);
		//get lab assignment
		$labAssignmentTicketObject = Celini::newOrdo("LabAssignmentTicket");
		$labAssignmentTicketObject->setup($labAssignmentTicketId);

		if ($labAssignmentTicketObject->getEnumStatus()
		== Utils::getEnumKey(EnumerationConstant::LAB_ASSIGNMENT_TICKET_STATUS,
		EnumerationConstant::LAB_ASSIGNMENT_TICKET_INPROGRESS)
		|| $labAssignmentTicketObject->getEnumStatus()
		== Utils::getEnumKey(EnumerationConstant::LAB_ASSIGNMENT_TICKET_STATUS,
		EnumerationConstant::LAB_ASSIGNMENT_TICKET_DONE)) {
			$canEdit = 0;
		} else {
			$canEdit = 1;
		}
		$labAssignmentTicketObject = Celini::newOrdo("LabAssignmentTicket");
		$labAssignmentTicketObject->setup($labAssignmentTicketId);
		$assignedLabServicesHtml = $this->buildHtmlLabAssignedServiceOption ($labAssignmentTicketObject);
		$this->controller->assign('canEdit', $canEdit);
		$this->controller->assign('treatmentDoctorId', $labAssignmentTicketObject->getTreatmentDoctorId());
		$requestTime = L10nHelper::renderDateTime($labAssignmentTicketObject->getRequestTime(),'short','datetime');
		$requestTimePart =  L10nHelper::getDateParts($requestTime);
		$this->controller->assign('requestTimePart', $requestTimePart);
			
		$this->controller->assign('diagnosis', $labAssignmentTicketObject->getDiagnosis());
		$this->controller->assign('assignedLabServicesHtml', $assignedLabServicesHtml);
		$this->controller->assign('labAssignmentModel', $labAssignmentModel->labGroupModelToArray());
		$orders =   L10nHelper::getYMDorder();
		$this->controller->assign('datePart_0', $orders[0]);
		$this->controller->assign('datePart_1', $orders[1]);
		$this->controller->assign('datePart_2', $orders[2]);
		return $this->controller->view->render('laboratory_assignment_vedit.html');

	}

	/**
	 * Build assigned lab service option for assigned service list.
	 * @param $labAssignmentTicketId
	 * @return html
	 */
	private function buildHtmlLabAssignedServiceOption($labAssignmentTicketObject) {
		if (!isset($labAssignmentTicketObject)) {
			return;
		}
		$labTicketObject = Celini::newOrdo("LabTicket");
		$labTicketList = $labTicketObject->listLabTickets($labAssignmentTicketObject->getLabAssignmentTicketId());
		$labAssignedItemObj = Celini::newOrdo("LabAssignedItem");
		$html = '';
		foreach ($labTicketList  as $labTicket) {
			$html .= "<optgroup groupid = '0' value='" . $labTicket['lab_group_id'] .
    		 "' label='" . $labTicket['name'] . "'>";
			$labAssignedItemList = $labAssignedItemObj->listLabAssignedItems($labTicket['lab_ticket_id']);

			foreach($labAssignedItemList as $labAssignedItem) {
				$text = L10nHelper::_("%s [Price:%s]",$labAssignedItem['name'], L10nHelper::renderNumber($labAssignedItem['patient_price'],0));
				$html .= "<option groupid='" . $labTicket['lab_group_id'] . "' ";
				$html .= " value='" . $labAssignedItem['service_id'] .  "' ";
				$html .= " price='" . $labAssignedItem['original_price'] .  "' ";
				$html .= " insurance_price='" . $labAssignedItem['insurance_price'] .  "' ";
				$html .= " patient_price='" . $labAssignedItem['patient_price'] .  "' ";
				$html .= ">";
				$html .= $text . "</option>";
			}

			$html .= "</optgroup>";
		}
		return $html;
	}

	/**
	 * List lab assignment of givent ticketId.
	 * @param $ticketId
	 * @return array[n](lab_assignment_ticket_id, request_time, diagnosis,
	 * <br>
	 *  PE.name treatment_doctor_name, treatment_doctor_id, enum_status, enum_status_text)
	 */

	public function listAssignments($ticketId) {
		$labAssignmentTicketObject = Celini::newOrdo("LabAssignmentTicket");
		$listAssignments = $labAssignmentTicketObject->listAssignments($ticketId);

		foreach ($listAssignments as &$assignment) {
			$assignment['enum_status_text'] = Utils::getEnumTextByKey(EnumerationConstant::LAB_ASSIGNMENT_TICKET_STATUS, $assignment['enum_status']);
			$assignment['request_time'] = L10nHelper::renderDateTime($assignment['request_time'], 'short', 'datetime');
		}
		return $listAssignments;
	}
	/**
	 * Delete all
	 * @param $ticketId
	 * @return unknown_type
	 */
	public function deleteAssignmentOfGivenTicketId($ticketId) {
		$listOfAssignment = $this->listAssignments($ticketId);
		//check could delete given ticket or not
		foreach ($listOfAssignment as $assignment) {
			if ($this->canDeleteAssignment($assignment['lab_assignment_ticket_id']) == false) {
				throw new LabException("Could not delete lab assignment has status[" .
				EnumerationConstant::LAB_ASSIGNMENT_TICKET_INPROGRESS . "," .
				EnumerationConstant::LAB_ASSIGNMENT_TICKET_DONE. "]", LabErrorCode::ASSIGNMENT_COULD_NOT_DELETE);
			}
		}
		//could delete all assignment of given ticketid
		foreach ($listOfAssignment as $assignment) {
			$this->deleteAssignment($assignment['lab_assignment_ticket_id']);
		}

	}
	public function canDeleteAssignment($labAssignmentTicketId) {
		$labAssignmentTicketObject = Celini::newOrdo("LabAssignmentTicket");
		$labAssignmentTicketObject->setup($labAssignmentTicketId);


		if ($labAssignmentTicketObject->getEnumStatus()
		== Utils::getEnumKey(EnumerationConstant::LAB_ASSIGNMENT_TICKET_STATUS,
		EnumerationConstant::LAB_ASSIGNMENT_TICKET_INPROGRESS)
		|| $labAssignmentTicketObject->getEnumStatus()
		== Utils::getEnumKey(EnumerationConstant::LAB_ASSIGNMENT_TICKET_STATUS,
		EnumerationConstant::LAB_ASSIGNMENT_TICKET_DONE)) {
			return false;
		}
		return true;
	}
	/**
	 * Delete a given lab assignment
	 *
	 * @param $labAssignmentTicketId
	 * @return id of deleted lab assignment
	 * @throw LabException
	 */
	public function deleteAssignment($labAssignmentTicketId) {
		$this->logger->info('start deleteAssignment: ' . $labAssignmentTicketId);
		$labAssignmentTicketObject = Celini::newOrdo("LabAssignmentTicket");
		$labAssignmentTicketObject->setup($labAssignmentTicketId);

		if ($this->canDeleteAssignment($labAssignmentTicketId) == false) {
			throw new LabException("Could not delete lab assignment has status[" .
			EnumerationConstant::LAB_ASSIGNMENT_TICKET_INPROGRESS . "," .
			EnumerationConstant::LAB_ASSIGNMENT_TICKET_DONE. "]", LabErrorCode::ASSIGNMENT_COULD_NOT_DELETE);
		}

		//delete lab_assignment_ticket
		$labAssignmentTicketObject->deleleLabAssignment($labAssignmentTicketId);
		//delete lab queue
		$labQueueObj = Celini::newOrdo("LabQueue");
		$labQueueObj->deleleQueueItem($labAssignmentTicketId);


		//delete all lab_ticket
		$labTicketsObj = Celini::newOrdo("LabTicket");
		$listLabTickets = $labTicketsObj->listLabTickets($labAssignmentTicketId);
		$labTicketsObj->deleleLabTickets($labAssignmentTicketId);
		//delete all lab_assigned_item
		$labAssignedItemObj = Celini::newOrdo("LabAssignedItem");
		$labAssignedItemResultObj = Celini::newOrdo("LabResult");
		foreach ($listLabTickets as $labTicket) {
			$listAssignedItem = $labAssignedItemObj->listLabAssignedItems($labTicket['lab_ticket_id'], true);
			//remove all result structure of this lab assigned item.
			$labAssignedItemResultObj->deleleItems($listAssignedItem);
			//remove this lab assigned item.
			$labAssignedItemObj->deleleAssignedItems($labTicket['lab_ticket_id']);
		}
		//do after lab assignment is deleted
		$this->processAfterDelete($labAssignmentTicketObject->getEnumPatientType(),
		$labAssignmentTicketObject->getTicketId(), $labAssignmentTicketId);
		$this->logger->info('finish deleteAssignment: ' . $labAssignmentTicketId);

		return $labAssignmentTicketId;

	}
	/**
	 * Call connector after delete lab assignment.
	 * @param $patientType
	 * @param $ticketId
	 * @param $labAssignmentTicketId
	 * @return nothing.
	 */
	private function processAfterDelete($patientType, $ticketId, $labAssignmentTicketId) {
		try {

			$fileLoader = new HISFileLoader();

			global $config;
			$labConfig = $config['laboratory'];
			//
			if ($patientType == Utils::getEnumKey(EnumerationConstant::PATIENT_TYPE,
			EnumerationConstant::PATIENT_TYPE_INPATIENT)) {
				if (isset($labConfig['inpatientconnector'])) {
					$inPatientConnector = $fileLoader->getObj($labConfig['inpatientconnector']);
					try {
						$inPatientConnector->doAfterAssignmentDeleted($ticketId, $labAssignmentTicketId);
					} catch (Exception $ex) {
						throw new LabException($ex->getMessage(), LabErrorCode::ASSIGNMENT_DELETING_FAIL);
					}
				}
			}  else if  ($patientType == Utils::getEnumKey(EnumerationConstant::PATIENT_TYPE,
			EnumerationConstant::PATIENT_TYPE_OUTPATIENT)) {
				if (isset($labConfig['outpatientconnector'])) {
					$outPatientConnector = $fileLoader->getObj($labConfig['outpatientconnector']);
					try {
						$outPatientConnector->doAfterAssignmentDeleted($ticketId, $labAssignmentTicketId);
					} catch (Exception $ex) {
						throw new LabException($ex->getMessage(), LabErrorCode::ASSIGNMENT_DELETING_FAIL);
					}

				}
			}
		} catch (EnumException $ex) {
			throw $ex;
		} catch (LabException $ex) {
			throw $ex;
		} catch (Exception $ex) {
			//all the error in this function not affect the logic of flow
			//this function success or fail is not mandotory
			//only log exception in debug mode
			$this->logger->debug($ex->getMessage());
		}

	}

	/**
	 * Call connector after delete lab assignment.
	 * @param $patientType
	 * @param $ticketId
	 * @param $labAssignmentTicketId
	 * @return nothing.
	 */
	private function processAfterAssignmentCreated($patientType, $ticketId, $labAssignmentTicketId, $data4ProcessAfterCreated) {
		try {

			$fileLoader = new HISFileLoader();

			global $config;
			$labConfig = $config['laboratory'];
			//
			if ($patientType == Utils::getEnumKey(EnumerationConstant::PATIENT_TYPE,
			EnumerationConstant::PATIENT_TYPE_INPATIENT)) {
				if (isset($labConfig['inpatientconnector'])) {
					$inPatientConnector = $fileLoader->getObj($labConfig['inpatientconnector']);
					try {
						$inPatientConnector->doAfterAssignmentCreated($ticketId, $labAssignmentTicketId, $data4ProcessAfterCreated);
						//add patient into lab queue
						$labQueueProcessor = new LabQueueProcessor();
						$labQueueProcessor->addPatient($labAssignmentTicketId);
					} catch (Exception $ex) {
						throw new LabException($ex->getMessage(), LabErrorCode::ASSIGNMENT_CREATING_FAIL);
					}

				}
			}  else if  ($patientType == Utils::getEnumKey(EnumerationConstant::PATIENT_TYPE,
			EnumerationConstant::PATIENT_TYPE_OUTPATIENT)) {
				if (isset($labConfig['outpatientconnector'])) {
					$outPatientConnector = $fileLoader->getObj($labConfig['outpatientconnector']);
					try {
						$outPatientConnector->doAfterAssignmentCreated($ticketId, $labAssignmentTicketId, $data4ProcessAfterCreated);
					} catch (Exception $ex) {
						throw new LabException($ex->getMessage(), LabErrorCode::ASSIGNMENT_CREATING_FAIL);
					}
				}
			}
		} catch (EnumException $ex) {
			throw $ex;
		} catch (LabException $ex) {
			throw $ex;
		} catch (Exception $ex) {
			//all the error in this function not affect the logic of flow
			//this function success or fail is not mandotory
			//only log exception in debug mode
			$this->logger->debug($ex->getMessage());
		}

	}
	/**
	 * Get list of lab services of given lab group id.
	 * @param $selectedGroupId
	 * @return Array(service_id,name)
	 */
	public function listLabServicesOfSelectedGroup($selectedGroupId) {
		$servicesObj = Celini::newOrdo("LabService");
		return $servicesObj->loadLabServices($selectedGroupId);
	}
	/**
	 *get price, insurance price, patient price for every service
	 *according to given ticketId
	 *<br>
	 * @param $ticketId
	 * @param $listOfService
	 * @return Array(service_id,name,price,insurance_price,patient_price)
	 */
	public function decoratePriceForServices($ticketId, &$listOfService) {
		$servicesObj = Celini::newOrdo("Service");
		foreach ($listOfService as &$service) {
			$prices = $servicesObj->getPrices($ticketId, $service['service_id'], EnumerationConstant::SER_INS_ITEM_TYPE_LAB);
			$service['price'] = $prices['price'];
			$service['insurance_price'] = $prices['insurance_price'];
			$service['patient_price'] = $prices['patient_price'];
		}
	}
	/**
	 * start lab assignment add it to queue.
	 * @param $labAssignmentTicket
	 * @return unknown_type
	 */
	public function startAssignment($labAssignmentTicketId) {
		$labAssignmentTicketObject = Celini::newOrdo("LabAssignmentTicket");
		$labAssignmentTicketObject->setup($labAssignmentTicketId);
		$enumStatus = $labAssignmentTicketObject->getEnumStatus();
		//only start assignment has status LAB_ASSIGNMENT_TICKET_ASSIGNED
		if ($enumStatus == Utils::getEnumKey(EnumerationConstant::LAB_ASSIGNMENT_TICKET_STATUS,
		EnumerationConstant::LAB_ASSIGNMENT_TICKET_ASSIGNED)) {
			$labAssignmentTicketObject->setEnumStatus(EnumerationConstant::LAB_ASSIGNMENT_TICKET_WAITING);
			$labAssignmentTicketObject->persist();
			return $labAssignmentTicketObject->get_id();
		} else {
			throw new LabException('this lab assignment['. $labAssignmentTicketId . '] already started',
			LabErrorCode::ASSIGNMENT_ALREADY_START);
		}
	}

	/**
	 * change lab assignment status.
	 * @param $labAssignmentTicket
	 * @return unknown_type
	 */
	public function changeLabAssignmentStatus($labAssignmentTicketId, $enumStatus) {
		$labAssignmentTicketObject = Celini::newOrdo("LabAssignmentTicket");
		$labAssignmentTicketObject->setup($labAssignmentTicketId);
		$labAssignmentTicketObject->setEnumStatus($enumStatus);
		$labAssignmentTicketObject->persist();
		return $labAssignmentTicketObject->get_id();
	}

	/**
	 * Create lab assignment.
	 * @param $labAssignmentTicket
	 * @return unknown_type
	 */
	public function createAssignment($labAssignmentTicketInfo) {
		//1.1 create lab_assignment_ticket
		$labAssignmentTicketObject = Celini::newOrdo("LabAssignmentTicket");
		$ticketObj = Celini::newOrdo('Ticket');
		$ticketObj->setup($labAssignmentTicketInfo['ticketId']);
		$enumStatus = '0';
		if (Utils::getEnumKey(EnumerationConstant::PATIENT_TYPE, EnumerationConstant::PATIENT_TYPE_INPATIENT)
		== $ticketObj->getEnumPatientType()) {
			$enumStatus = Utils::getEnumKey(EnumerationConstant::LAB_ASSIGNMENT_TICKET_STATUS,
			EnumerationConstant::LAB_ASSIGNMENT_TICKET_WAITING);
		} else if (Utils::getEnumKey(EnumerationConstant::PATIENT_TYPE, EnumerationConstant::PATIENT_TYPE_OUTPATIENT)
		== $ticketObj->getEnumPatientType()) {
			$enumStatus = Utils::getEnumKey(EnumerationConstant::LAB_ASSIGNMENT_TICKET_STATUS,
			EnumerationConstant::LAB_ASSIGNMENT_TICKET_ASSIGNED);
		}
		$labAssignmentTicket = array(
		'ticket_id'               =>$labAssignmentTicketInfo['ticketId'],
		'treatment_doctor_id'     =>$labAssignmentTicketInfo['doctorId'],
		'treatment_department_id' =>$ticketObj->getDepartmentId(),
		'enum_status'             =>$enumStatus,
		'request_time'            =>$labAssignmentTicketInfo['requestedTime'],
		'patient_id'              =>$ticketObj->getPatientId(),
		'diagnosis'               =>$labAssignmentTicketInfo['diagnosis'],
		'enum_patient_type'       =>$ticketObj->getEnumPatientType()
		);
		$labAssignmentTicketObject->setData($labAssignmentTicket);
		$labAssignmentTicketObject->persist();
		$labAssignmentTicketId = $labAssignmentTicketObject->get_id();

		$labTickets = array();
		$data4ProcessAfterCreated = array(
		'date'=>$labAssignmentTicketInfo['requestedTime'],
		'item_id'=>$labAssignmentTicketId,		
		'original_price'=>0,
		'insurance_price'=>0,
		'insurance_price'=>0,
		'patient_price'=>0,
		'ticket_id'=>$labAssignmentTicketInfo['ticketId']
		);

		for ($index = 0;
		$index < count($labAssignmentTicketInfo['labAssignedItem']);
		$index++) {
			$labGroupId = $labAssignmentTicketInfo['labGroup'][$index];
			if (!isset($labTickets[$labGroupId])) {
				//create lab ticket if not create yet.
				$labTicketObj = Celini::newOrdo("LabTicket");
				$labTicketInfo = array(
				'lab_assignment_ticket_id'  =>$labAssignmentTicketId,
				'is_done'                   =>0,
				'lab_group_id'              =>$labGroupId);
				$labTicketObj->setData($labTicketInfo);
				$labTicketObj->persist();
				$labTicketId = $labTicketObj->get_id();
				$labTickets[$labGroupId] = $labTicketId;
			}
			$seviceObj = Celini::newOrdo("Service");
			$prices = $seviceObj->getPrices(
			$labAssignmentTicketInfo['ticketId'],
			$labAssignmentTicketInfo['labAssignedItem'][$index],
			EnumerationConstant::SER_INS_ITEM_TYPE_LAB);
			$data4ProcessAfterCreated['original_price'] += $prices['price'];
			$data4ProcessAfterCreated['insurance_price'] += $prices['insurance_price'];
			$data4ProcessAfterCreated['patient_price'] += $prices['patient_price'];
			//create lab_assigned_item
			$labAssignedItemInfo = array(
				'lab_ticket_id'  =>$labTickets[$labGroupId],
				'service_id'     =>$labAssignmentTicketInfo['labAssignedItem'][$index],
				'original_price' =>$prices['price'],
				'insurance_price'=>$prices['insurance_price'],
				'patient_price'  =>$prices['patient_price'],
				'is_done'        =>0			
			);
			$labAssignedItemObj = Celini::newOrdo("LabAssignedItem");
			$labAssignedItemObj->setData($labAssignedItemInfo);
			$labAssignedItemObj->persist();
			//create structure for input result.
			$labResultObj = Celini::newOrdo('LabResult');
			$labResultObj->createResultStructure($labAssignedItemObj->get_id(),
			$labAssignmentTicketInfo['labAssignedItem'][$index]);

		}

		$this->processAfterAssignmentCreated($labAssignmentTicketObject->getEnumPatientType(),
		$labAssignmentTicketObject->getTicketId(), $labAssignmentTicketId, $data4ProcessAfterCreated);


		//end create lab assignment
		return $labAssignmentTicketId;

	}

	public function finishAssignment($labAssignmentTicketId) {
		$labAssignmentTicketObj = Celini::newOrdo('LabAssignmentTicket');
		$labAssignmentTicketObj->setup($labAssignmentTicketId);
		$prices = $labAssignmentTicketObj->calculatePrices();
		//call connector
		try {
			$patientType = $labAssignmentTicketObj->getEnumPatientType();
			$ticketId = $labAssignmentTicketObj->getTicketId();

			$fileLoader = new HISFileLoader();

			global $config;
			$labConfig = $config['laboratory'];
			//
			if ($patientType == Utils::getEnumKey(EnumerationConstant::PATIENT_TYPE,
			EnumerationConstant::PATIENT_TYPE_INPATIENT)) {
				if (isset($labConfig['inpatientconnector'])) {
					$inPatientConnector = $fileLoader->getObj($labConfig['inpatientconnector']);
					try {
						$inPatientConnector->doAfterAssignmentFinished($ticketId, $labAssignmentTicketId, $prices);
					} catch (Exception $ex) {
						throw new LabException($ex->getMessage(), LabErrorCode::ASSIGNMENT_FINISHING_FAIL);
					}

				}
			}  else if  ($patientType == Utils::getEnumKey(EnumerationConstant::PATIENT_TYPE,
			EnumerationConstant::PATIENT_TYPE_OUTPATIENT)) {
				if (isset($labConfig['outpatientconnector'])) {
					$outPatientConnector = $fileLoader->getObj($labConfig['outpatientconnector']);
					try {
						$outPatientConnector->doAfterAssignmentFinished($ticketId, $labAssignmentTicketId, $prices);
					} catch (Exception $ex) {
						throw new LabException($ex->getMessage(), LabErrorCode::ASSIGNMENT_FINISHING_FAIL);
					}
				}
			}
		} catch (EnumException $ex) {
			throw $ex;
		} catch (LabException $ex) {
			throw $ex;
		} catch (Exception $ex) {
			//all the error in this function not affect the logic of flow
			//this function success or fail is not mandotory
			//only log exception in debug mode
			$this->logger->debug($ex->getMessage());
		}
	}

	public function doWhileAssignmentProcessing($labAssignmentTicketId) {
		$labAssignmentTicketObj = Celini::newOrdo('LabAssignmentTicket');
		$labAssignmentTicketObj->setup($labAssignmentTicketId);

		//call connector
		try {
			$patientType = $labAssignmentTicketObj->getEnumPatientType();
			$ticketId = $labAssignmentTicketObj->getTicketId();

			$fileLoader = new HISFileLoader();

			global $config;
			$labConfig = $config['laboratory'];
			//
			if ($patientType == Utils::getEnumKey(EnumerationConstant::PATIENT_TYPE,
			EnumerationConstant::PATIENT_TYPE_INPATIENT)) {
				if (isset($labConfig['inpatientconnector'])) {
					$inPatientConnector = $fileLoader->getObj($labConfig['inpatientconnector']);
					try {
						$inPatientConnector->doWhileAssignmentProcessing($ticketId, $labAssignmentTicketId);
					} catch (Exception $ex) {
						throw new LabException($ex->getMessage(), LabErrorCode::ASSIGNMENT_FINISHING_FAIL);
					}

				}
			}  else if  ($patientType == Utils::getEnumKey(EnumerationConstant::PATIENT_TYPE,
			EnumerationConstant::PATIENT_TYPE_OUTPATIENT)) {
				if (isset($labConfig['outpatientconnector'])) {
					$outPatientConnector = $fileLoader->getObj($labConfig['outpatientconnector']);
					try {
						$outPatientConnector->doWhileAssignmentProcessing($ticketId, $labAssignmentTicketId);
					} catch (Exception $ex) {
						throw new LabException($ex->getMessage(), LabErrorCode::ASSIGNMENT_FINISHING_FAIL);
					}
				}
			}
		} catch (EnumException $ex) {
			throw $ex;
		} catch (LabException $ex) {
			throw $ex;
		} catch (Exception $ex) {
			//all the error in this function not affect the logic of flow
			//this function success or fail is not mandotory
			//only log exception in debug mode
			$this->logger->debug($ex->getMessage());
		}
	}

	public function doAfterAssignmentCanceled($labAssignmentTicketId) {
		$labAssignmentTicketObj = Celini::newOrdo('LabAssignmentTicket');
		$labAssignmentTicketObj->setup($labAssignmentTicketId);

		//call connector
		try {
			$patientType = $labAssignmentTicketObj->getEnumPatientType();
			$ticketId = $labAssignmentTicketObj->getTicketId();

			$fileLoader = new HISFileLoader();

			global $config;
			$labConfig = $config['laboratory'];
			//
			if ($patientType == Utils::getEnumKey(EnumerationConstant::PATIENT_TYPE,
			EnumerationConstant::PATIENT_TYPE_INPATIENT)) {
				if (isset($labConfig['inpatientconnector'])) {
					$inPatientConnector = $fileLoader->getObj($labConfig['inpatientconnector']);
					try {
						$inPatientConnector->doAfterAssignmentCanceled($ticketId, $labAssignmentTicketId);
					} catch (Exception $ex) {
						throw new LabException($ex->getMessage(), LabErrorCode::ASSIGNMENT_FINISHING_FAIL);
					}

				}
			}  else if  ($patientType == Utils::getEnumKey(EnumerationConstant::PATIENT_TYPE,
			EnumerationConstant::PATIENT_TYPE_OUTPATIENT)) {
				if (isset($labConfig['outpatientconnector'])) {
					$outPatientConnector = $fileLoader->getObj($labConfig['outpatientconnector']);
					try {
						$outPatientConnector->doAfterAssignmentCanceled($ticketId, $labAssignmentTicketId);
					} catch (Exception $ex) {
						throw new LabException($ex->getMessage(), LabErrorCode::ASSIGNMENT_FINISHING_FAIL);
					}
				}
			}
		} catch (EnumException $ex) {
			throw $ex;
		} catch (LabException $ex) {
			throw $ex;
		} catch (Exception $ex) {
			//all the error in this function not affect the logic of flow
			//this function success or fail is not mandotory
			//only log exception in debug mode
			$this->logger->debug($ex->getMessage());
		}
	}

	public function renderLabAssignment4Print($labAssignmentTicketId) {
		$labAssignmentTicketObj = Celini::newOrdo('LabAssignmentTicket');
		$labAssignmentTicket = $labAssignmentTicketObj->getAssignmentInfo($labAssignmentTicketId);
		$person = Celini::newORDO('Person', $labAssignmentTicket['patient_id']);
		$patient = Celini::newORDO('Patient', $labAssignmentTicket['patient_id']);
		$this->controller->assign('gender', $person->getGender());
		$this->controller->assign('address', $person->getAddress());
		$this->controller->assign('phone', $person->getPhoneNumber());
		$this->controller->assign('patientName', $person->getName());
		$this->controller->assign('patientId', $labAssignmentTicket['patient_id']);
		$this->controller->assign('patientCode', $patient->get('patient_code'));
		$this->controller->assign('patientDob', $person->getDateofBirth());
		$this->controller->assign('patientAge', $person->getAge());


		$this->controller->assign('treatmentDoctorName', '');
		$this->controller->assign('diagnosis', '');
		$this->controller->assign('requestTime', '');
		$this->controller->assign('treatmentDepartmentName', '');

		if ($labAssignmentTicket != null) {

			$this->controller->assign('treatmentDoctorName', $labAssignmentTicket['treatment_doctor_name']);
			$this->controller->assign('diagnosis', $labAssignmentTicket['diagnosis']);
			$this->controller->assign('requestTime', $labAssignmentTicket['request_time']);
			$this->controller->assign('treatmentDepartmentName', $labAssignmentTicket['treatment_department_name']);

		}



		$labResultEngine = new LabResultEngine();
		$labTicketObj = Celini::newOrdo('LabTicket');
		$listOfLabTicket = $labTicketObj->listLabTickets($labAssignmentTicketId, true);

		$html = '';
		$html .= '<table cellspacing="0" cellpadding="0" style="width: 100%; margin-bottom: 10px;" class="grid">';
		$html .= '<thead>
                    <tr>
                        <th style="width: 30%;">'. L10nHelper::_('Group') . '</th>
                        <th style="width: 50%;">'. L10nHelper::_('Service') . '</th>                        
                        <th style="width: 20%;">'. L10nHelper::_('Price') . '</th>
                    </tr>
                </thead>';
		$count = 1;
		$totalPrice = 0;
		foreach ($listOfLabTicket as $labTicket) {
			$labResultModel = $labResultEngine->getLabModel($labTicket['lab_ticket_id']);
			$labTicketinfo = $labResultModel->getLabTicketOrdo()->getLabTicket();
			$labAssignedItems = $labResultModel->getLabAssignedItemsModel();
			$html .= "<tr>";
			$html .= "<td>" . $labTicketinfo['name'] . " &nbsp;</td>";
			$html .= "<td>&nbsp;</td>";
			$html .= "<td>&nbsp;</td>";
			$html .= "</tr>";
			foreach ($labAssignedItems as $item) {
				$html .= "<tr>";
				$html .= "<td>&nbsp;</td>";
				$html .= "<td>" . $item->getLabAssignedItemOrdo()->getNameText() . "&nbsp;</td>";
				$html .= "<td>" . L10nHelper::renderCurrency($item->getLabAssignedItemOrdo()->getPatientPrice()) . "&nbsp;</td>";
				$html .= "</tr>";
				if (trim($item->getLabAssignedItemOrdo()->getPatientPrice()) != '') {
				    $totalPrice += $item->getLabAssignedItemOrdo()->getPatientPrice(); 
				}
			}
			
		}
		$html .= "<tr>";
		$html .= '<td colspan="2" style="text-align: right;">' . L10nHelper::_("Total") .  '</td>';
		$html .= '<td >' . L10nHelper::_("%s VND", L10nHelper::renderNumber($totalPrice)) . "</td>";                    
		$html .= "</tr>";
		$html .= '</table>';

		$this->controller->assign('assignmentContent', $html);


		return $this->controller->view->render('laboratory_assignment_print.html');

	}
	
	public function countAllLabAssignmentByTicketId($ticketId) {
	    $labAssignmentTicketObj = Celini::newOrdo('LabAssignmentTicket');
	    $result = $labAssignmentTicketObj->listAssignmentsByTicketId($ticketId,
	    Array(
	    EnumerationConstant::LAB_ASSIGNMENT_TICKET_ASSIGNED,
        EnumerationConstant::LAB_ASSIGNMENT_TICKET_WAITING,
        EnumerationConstant::LAB_ASSIGNMENT_TICKET_INPROGRESS,
        EnumerationConstant::LAB_ASSIGNMENT_TICKET_DONE,
        ));	    
	    return count($result);
	    
	}
    
}
?>